package com.gitee.qdbp.general.thirdpart.biz.trade.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.general.thirdpart.api.alipay.model.AlipayPayee;
import com.gitee.qdbp.general.thirdpart.api.trade.model.OrderData;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PaidNotify;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PaidResponse;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayData;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayParams;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayResponse;
import com.gitee.qdbp.general.thirdpart.api.trade.service.IPaymentBusinessService;
import com.gitee.qdbp.general.thirdpart.api.wechat.model.WechatPayee;
import com.gitee.qdbp.general.thirdpart.error.PaymentErrorCode;
import com.gitee.qdbp.general.trade.enums.PaySource;
import com.gitee.qdbp.tools.utils.JsonTools;
import com.gitee.qdbp.tools.utils.VerifyTools;
/**
 * 基础交易处理逻辑
 *
 * @author zhaohuihua
 * @version 180425
 */
public class BaseTradeService {

    /** 日志对象 **/
    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    private String type;

    public BaseTradeService(String type) {
        this.type = type;
    }

    @Autowired
    private IPaymentBusinessService paymentBusinessService;

    // 查询支付宝收款人信息(支付前)
    protected AlipayPayee doGetAlipayPayee(PrepayData params, PaySource paySource, AlipayPayee defaults) throws ServiceException {
        AlipayPayee payee;
        try {
            payee = paymentBusinessService.getAlipayPayee(params, paySource, defaults);
        } catch (ServiceException e) {
            String m = "[{}]GetAlipayPayeeError, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(params));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]GetAlipayPayeeSuccess: {}", type, payee.getAppId());
        }
        return payee;
    }

    // 查询支付宝收款人信息(支付后)
    protected AlipayPayee doGetAlipayPayee(OrderData data, PaidNotify notify, AlipayPayee defaults)
            throws ServiceException {
        AlipayPayee payee;
        try {
            payee = paymentBusinessService.getAlipayPayee(data, notify, defaults);
        } catch (ServiceException e) {
            String m = "[{}]GetAlipayPayeeError, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(data, notify));
            throw e;
        }
        String payeeAccount = data.getPayeeAccount();
        if (VerifyTools.isNotBlank(payeeAccount) && !payeeAccount.equals(payee.getAppId())) {
            if (log.isErrorEnabled()) {
                String m = "[{}]NotifyParamsError: params.appId[{}] not equals payee.appId[{}]. {}";
                log.error(m, type, payeeAccount, payee.getAppId(), JsonTools.newlineLogs(data, notify));
            }
            throw new ServiceException(PaymentErrorCode.PAYMENT_PASSBACK_CHECK_FAILED);
        }

        if (log.isTraceEnabled()) {
            log.trace("[{}]GetAlipayPayeeSuccess: {}", type, payee.getAppId());
        }
        return payee;
    }

    // 查询微信收款人信息(支付前)
    protected WechatPayee doGetWechatPayee(PrepayData params, PaySource paySource, WechatPayee defaults) throws ServiceException {
        WechatPayee payee;
        try {
            payee = paymentBusinessService.getWechatPayee(params, paySource, defaults);
        } catch (ServiceException e) {
            String m = "[{}]GetWechatPayeeError, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(params));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]GetWechatPayeeSuccess: {}", type, payee.getAppId());
        }
        return payee;
    }

    // 查询微信收款人信息(支付后)
    protected WechatPayee doGetWechatPayee(OrderData data, PaidNotify notify, WechatPayee defaults)
            throws ServiceException {
        WechatPayee payee;
        try {
            payee = paymentBusinessService.getWechatPayee(data, notify, defaults);
        } catch (ServiceException e) {
            String m = "[{}]GetWechatPayeeError, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(data, notify));
            throw e;
        }
        String payeeAccount = data.getPayeeAccount();
        if (VerifyTools.isNotBlank(payeeAccount) && !payeeAccount.equals(payee.getAppId())) {
            if (log.isErrorEnabled()) {
                String m = "[{}]NotifyParamsError: params.appId[{}] not equals payee.appId[{}]. {}";
                log.error(m, type, payeeAccount, payee.getAppId(), JsonTools.newlineLogs(data, notify));
            }
            throw new ServiceException(PaymentErrorCode.PAYMENT_PASSBACK_CHECK_FAILED);
        }

        if (log.isTraceEnabled()) {
            log.trace("[{}]GetWechatPayeeSuccess: {}", type, payee.getAppId());
        }
        return payee;
    }

    // 预付单创建成功的处理
    protected void doPrepaySuccess(PrepayData prepayData, PrepayResponse response) throws ServiceException {
        String orderId = prepayData.getOrderId();

        // 处理订单: 修改付款状态为支付中
        try {
            paymentBusinessService.onPrepayHandleOrder(prepayData, response);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPrepayHandleOrder, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(prepayData));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]PrepayHandleOrderSuccess: orderId={}", type, orderId);
        }
        // 处理业务逻辑: 锁定库存
        try {
            paymentBusinessService.onPrepayHandleBusiness(prepayData, response);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPrepayHandleBusiness, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(prepayData));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]PrepayHandleBusiness: orderId={}", type, orderId);
        }
    }

    // 预付单创建失败的处理
    protected void doPrepayError(PrepayData prepayData, PrepayResponse response) throws ServiceException {
        String orderId = prepayData.getOrderId();
        try {
            paymentBusinessService.onPrepayHandleError(prepayData, response);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPrepayError, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(prepayData));
        }
        if (log.isInfoEnabled()) {
            log.info("[{}]PrepayHandleErrorSuccess. orderId={}", type, orderId);
        }
    }

    // 创建预付单前检查订单
    protected PrepayData doPrepayCheckOrder(PrepayParams params) throws ServiceException {

        // 检查订单, 检查支付状态
        PrepayData prepayData;
        try {
            prepayData = paymentBusinessService.onPrepayCheckOrder(params);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPrepayCheckOrder, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(params));
            throw e;
        }
        if (prepayData == null) {
            String m = "[{}]CheckOrderError: onPrepayCheckOrder return null. {}";
            log.error(m, type, JsonTools.newlineLogs(params));
            throw new ServiceException(ResultCode.SERVER_INNER_ERROR);
        }
        if (prepayData.getTotalAmount() == null) {
            String m = "[{}]CheckOrderError: onPrepayCheckOrder totalAmount return null. {}";
            log.error(m, type, JsonTools.newlineLogs(params));
            throw new ServiceException(ResultCode.SERVER_INNER_ERROR);
        }
        if (VerifyTools.isBlank(prepayData.getOrderTitle())) {
            String m = "[{}]CheckOrderError: onPrepayCheckOrder orderTitle return null. {}";
            log.error(m, type, JsonTools.newlineLogs(params));
            throw new ServiceException(ResultCode.SERVER_INNER_ERROR);
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]CheckOrderSuccess: {}", type, JsonTools.newlineLogs(prepayData));
        }
        if (VerifyTools.isBlank(prepayData.getOrderId())) {
            prepayData.setOrderId(params.getOrderId());
        }
        return prepayData;
    }

    // 创建预付单前业务逻辑检查(如检查库存)
    protected void doPrepayCheckBusiness(PrepayData prepayData) throws ServiceException {
        String orderId = prepayData.getOrderId();
        // 检查库存
        try {
            paymentBusinessService.onPrepayCheckBusiness(prepayData);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPrepayCheckBusiness, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(prepayData));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]CheckBusinessSuccess: orderId={}", type, orderId);
        }
    }

    // 创建付款单编号
    protected String doGeneratePaymentId(PrepayData prepayData) throws ServiceException {
        String newPaymentId;
        try {
            newPaymentId = paymentBusinessService.generatePaymentId(prepayData);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: generatePaymentId, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(prepayData));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]GeneratePaymentIdSuccess: {}", type, newPaymentId);
        }
        return newPaymentId;
    }

    // 支付成功后回调时查询和检查订单
    protected OrderData doPaidQueryOrder(PaidNotify notify) throws ServiceException {
        OrderData order;
        try {
            order = paymentBusinessService.onPaidQueryOrder(notify);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPaidQueryOrder. {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(notify));
            throw e;
        }
        if (order == null) {
            return null;
        }

        if (VerifyTools.isBlank(order.getOrderId())) {
            String m = "[{}]PaidQueryOrderError: onPaidQueryOrder orderId return null. {}";
            log.error(m, type, JsonTools.newlineLogs(notify));
            throw new ServiceException(ResultCode.SERVER_INNER_ERROR);
        }

        if (VerifyTools.isBlank(order.getOrderType())) {
            order.setOrderType(notify.getOrderType());
        }
        if (VerifyTools.isBlank(order.getPayChannel())) {
            order.setPayChannel(notify.getPayChannel());
        }
        if (VerifyTools.isBlank(order.getPaySource())) {
            order.setPaySource(notify.getPaySource());
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]PaidQueryOrderSuccess: {}", type, JsonTools.newlineLogs(notify, order));
        }
        return order;
    }

    // 支付成功后回调时处理业务逻辑
    protected void doNotifyHandleSuccess(OrderData order, PaidNotify notify, PaidResponse response)
            throws ServiceException {
        String orderId = order.getOrderId();

        // 修改付款状态
        boolean handleOrderSucc;
        try {
            handleOrderSucc = paymentBusinessService.onPaidHandleOrder(order, notify, response);
        } catch (ServiceException e) {
            String m = "[{}]InvokeError: onPaidHandleOrder, {}. {}";
            log.error(m, type, e.toString(), JsonTools.newlineLogs(order, notify, response));
            throw e;
        }
        if (log.isTraceEnabled()) {
            log.trace("[{}]PaidHandleOrderSuccess: orderId={}, result={}", type, orderId, handleOrderSucc);
        }
        // 核减库存/自动发货
        if (handleOrderSucc) {
            try {
                paymentBusinessService.onPaidHandleBusiness(order, notify, response);
            } catch (ServiceException e) {
                String m = "[{}]InvokeError: onPaidHandleBusiness, {}. {}";
                log.error(m, type, e.toString(), JsonTools.newlineLogs(order, notify, response));
                throw e;
            }
            if (log.isTraceEnabled()) {
                log.trace("[{}]PaidHandleBusinessSuccess: orderId={}", type, orderId);
            }
        }
    }
}
